package com.xxl.job.executor.service.jobhandler;

import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.context.XxlJobContext;
import com.xxl.job.core.handler.IJobHandler;
import com.xxl.job.core.handler.annotation.XxlJob;
import com.xxl.job.core.log.XxlJobLogger;


import com.xxl.job.executor.dao.QxMapMapper;
import com.xxl.job.executor.dao.QxWeatherMapper;
import com.xxl.job.executor.model.QxMap;
import com.xxl.job.executor.model.QxWeather;
import com.xxl.job.executor.utils.CmUtil;
import com.xxl.job.executor.utils.ConstUtil;
import org.jsoup.select.Elements;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * XxlJob开发示例（Bean模式）
 *
 * 开发步骤：
 * 1、在Spring Bean实例中，开发Job方法，方式格式要求为 "public ReturnT<String> execute(String param)"
 * 2、为Job方法添加注解 "@XxlJob(value="自定义jobhandler名称", init = "JobHandler初始化方法", destroy = "JobHandler销毁方法")"，注解value值对应的是调度中心新建任务的JobHandler属性的值。
 * 3、执行日志：需要通过 "XxlJobLogger.log" 打印执行日志；
 *
 * @author xuxueli 2019-12-11 21:52:51
 */
@Component
public class SampleXxlJob {
    private static Logger logger = LoggerFactory.getLogger(SampleXxlJob.class);



    private ConstUtil constUtil;
    /**
     * 1、简单任务示例（Bean模式）
     */
    @XxlJob("demoJobHandler")
    public ReturnT<String> demoJobHandler(String param) throws Exception {
        XxlJobLogger.log("XXL-JOB, Hello World.");

        for (int i = 0; i < 5; i++) {
            XxlJobLogger.log("beat at:" + i);
            TimeUnit.SECONDS.sleep(2);
        }
        return ReturnT.SUCCESS;
    }


    /**
     * 2、分片广播任务
     */
    @XxlJob("shardingJobHandler")
    public ReturnT<String> shardingJobHandler(String param) throws Exception {

        // 分片参数
        int shardIndex = XxlJobContext.getXxlJobContext().getShardIndex();
        int shardTotal = XxlJobContext.getXxlJobContext().getShardTotal();

        XxlJobLogger.log("分片参数：当前分片序号 = {}, 总分片数 = {}", shardIndex, shardTotal);

        // 业务逻辑
        for (int i = 0; i < shardTotal; i++) {
            if (i == shardIndex) {
                XxlJobLogger.log("第 {} 片, 命中分片开始处理", i);
            } else {
                XxlJobLogger.log("第 {} 片, 忽略", i);
            }
        }

        return ReturnT.SUCCESS;
    }


    /**
     * 3、命令行任务
     */
    @XxlJob("commandJobHandler")
    public ReturnT<String> commandJobHandler(String param) throws Exception {
        String command = param;
        int exitValue = -1;

        BufferedReader bufferedReader = null;
        try {
            // command process
            Process process = Runtime.getRuntime().exec(command);
            BufferedInputStream bufferedInputStream = new BufferedInputStream(process.getInputStream());
            bufferedReader = new BufferedReader(new InputStreamReader(bufferedInputStream));

            // command log
            String line;
            while ((line = bufferedReader.readLine()) != null) {
                XxlJobLogger.log(line);
            }

            // command exit
            process.waitFor();
            exitValue = process.exitValue();
        } catch (Exception e) {
            XxlJobLogger.log(e);
        } finally {
            if (bufferedReader != null) {
                bufferedReader.close();
            }
        }

        if (exitValue == 0) {
            return IJobHandler.SUCCESS;
        } else {
            return new ReturnT<String>(IJobHandler.FAIL.getCode(), "command exit value("+exitValue+") is failed");
        }
    }


    /**
     * 4、跨平台Http任务
     *  参数示例：
     *      "url: http://www.baidu.com\n" +
     *      "method: get\n" +
     *      "data: content\n";
     */
    @XxlJob("httpJobHandler")
    public ReturnT<String> httpJobHandler(String param) throws Exception {

        // param parse
        if (param==null || param.trim().length()==0) {
            XxlJobLogger.log("param["+ param +"] invalid.");
            return ReturnT.FAIL;
        }
        String[] httpParams = param.split("\n");
        String url = null;
        String method = null;
        String data = null;
        for (String httpParam: httpParams) {
            if (httpParam.startsWith("url:")) {
                url = httpParam.substring(httpParam.indexOf("url:") + 4).trim();
            }
            if (httpParam.startsWith("method:")) {
                method = httpParam.substring(httpParam.indexOf("method:") + 7).trim().toUpperCase();
            }
            if (httpParam.startsWith("data:")) {
                data = httpParam.substring(httpParam.indexOf("data:") + 5).trim();
            }
        }

        // param valid
        if (url==null || url.trim().length()==0) {
            XxlJobLogger.log("url["+ url +"] invalid.");
            return ReturnT.FAIL;
        }
        if (method==null || !Arrays.asList("GET", "POST").contains(method)) {
            XxlJobLogger.log("method["+ method +"] invalid.");
            return ReturnT.FAIL;
        }
        boolean isPostMethod = method.equals("POST");

        // request
        HttpURLConnection connection = null;
        BufferedReader bufferedReader = null;
        try {
            // connection
            URL realUrl = new URL(url);
            connection = (HttpURLConnection) realUrl.openConnection();

            // connection setting
            connection.setRequestMethod(method);
            connection.setDoOutput(isPostMethod);
            connection.setDoInput(true);
            connection.setUseCaches(false);
            connection.setReadTimeout(5 * 1000);
            connection.setConnectTimeout(3 * 1000);
            connection.setRequestProperty("connection", "Keep-Alive");
            connection.setRequestProperty("Content-Type", "application/json;charset=UTF-8");
            connection.setRequestProperty("Accept-Charset", "application/json;charset=UTF-8");

            // do connection
            connection.connect();

            // data
            if (isPostMethod && data!=null && data.trim().length()>0) {
                DataOutputStream dataOutputStream = new DataOutputStream(connection.getOutputStream());
                dataOutputStream.write(data.getBytes("UTF-8"));
                dataOutputStream.flush();
                dataOutputStream.close();
            }

            // valid StatusCode
            int statusCode = connection.getResponseCode();
            if (statusCode != 200) {
                throw new RuntimeException("Http Request StatusCode(" + statusCode + ") Invalid.");
            }

            // result
            bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
            StringBuilder result = new StringBuilder();
            String line;
            while ((line = bufferedReader.readLine()) != null) {
                result.append(line);
            }
            String responseMsg = result.toString();

            XxlJobLogger.log(responseMsg);
            return ReturnT.SUCCESS;
        } catch (Exception e) {
            XxlJobLogger.log(e);
            return ReturnT.FAIL;
        } finally {
            try {
                if (bufferedReader != null) {
                    bufferedReader.close();
                }
                if (connection != null) {
                    connection.disconnect();
                }
            } catch (Exception e2) {
                XxlJobLogger.log(e2);
            }
        }

    }

    /**
     * 5、生命周期任务示例：任务初始化与销毁时，支持自定义相关逻辑；
     */

    @XxlJob(value = "demoJobHandler2", init = "init", destroy = "destroy")
    public ReturnT<String> demoJobHandler2(String param) throws Exception {
        XxlJobLogger.log("XXL-JOB, Hello World.");
        System.out.println("1++++++++++++++++++");



        String imgUrl = "";
        String dataTime = "";
        String time = "";
        String mediumImgUrl = "";
        // 获取html文本内容
        Document doc = getHtml();

        Element img = doc.select("[id=\"imgpath\"]").first();
        mediumImgUrl = img.attr("src");
        dataTime = img.attr("data-time");
        time = mediumImgUrl.substring(mediumImgUrl.lastIndexOf("_") + 1, mediumImgUrl.lastIndexOf("_") + 9) + dataTime.substring(dataTime.lastIndexOf(" "));


        String taskContents = "imgUrl=" + mediumImgUrl + "______time=" + time;
        // 下载图片
        Download(mediumImgUrl, time);
        return ReturnT.SUCCESS;
    }


    public static Document getHtml() {
        Document doc = null;
        try {

            doc = Jsoup.connect("http://www.nmc.cn/publish/radar/huabei.html")
                    .userAgent("Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0; MALC)")
                    .timeout(999999999)
                    .header("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8")
                    .header("Accept-Encoding", "gzip, deflate")
                    .header("Accept-Language", "zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3")
                    .header("Connection", "keep-alive")
                    //是忽略请求类型
                    .ignoreContentType(true)
                    .get();

        } catch (Exception e) {
            e.printStackTrace();
        }
        return doc;
    }
    /**
     * 下载图片
     *
     * @param imgUrl
     * @param time
     */
    private void Download(String imgUrl, String time) {
        HttpURLConnection connection;
        if (imgUrl.length() > 0 && time.length() > 0) {

            // 根据时间和图像类型判断当前图片是否已下载
            String type = 3+"";
                InputStream in = null;
                FileOutputStream fo = null;
                try {
                    String imageName = imgUrl.substring(imgUrl.lastIndexOf("/") + 1, imgUrl.length());
                    imageName = imageName.substring(0, imageName.lastIndexOf("?"));
                    URL uri = new URL(imgUrl);

                    System.out.println("OK"+ imageName);
                } catch (Exception e) {
                    e.printStackTrace();
                    System.out.println("1");
                } finally {
                    try {
                        if (fo != null) {
                            fo.flush();
                            fo.close();
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    try {
                        if (in != null) {
                            in.close();
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }
   // }

    /*
    * "卫星云图（海区红外云图）数据抓取"
    */

    @XxlJob(value = "SatilliteCloudImageCnpoTask", init = "init", destroy = "destroy")
    public ReturnT<String> SatilliteCloudImageCnpoTask(String param) throws Exception {


        String imgUrl = "";
        String dataTime = "";
        String time = "";
        String mediumImgUrl = "";
        // 获取html文本内容
        Document doc = getHtml1();
        //if (doc == null) return;
       /* mediumImgUrl = doc.select("[id=\"imgpath\"]").attr("src");
        Element firstLi = doc.select("ul[id=\"mycarousel\"]").select("li").first();
        // 获取图片标签
        Element firstImg = firstLi.select("img").first();
        // 获取图片地址
        if (null != firstImg) {
            imgUrl = firstImg.attr("data-original");
        }
        // 获取时间标签
        Element firstTime = firstLi.select("p[class=\"time\"]").first();
        // 获取时间
        if (null != firstTime) {
            time = firstTime.text();
        }*/

        Element img = doc.select("[id=\"imgpath\"]").first();
        mediumImgUrl = img.attr("src");
        dataTime = img.attr("data-time");
        time = mediumImgUrl.substring(mediumImgUrl.lastIndexOf("_") + 1, mediumImgUrl.lastIndexOf("_") + 9) + dataTime.substring(dataTime.lastIndexOf(" "));


       /// this.taskContents = "imgUrl=" + mediumImgUrl + "______time=" + time;
        // 下载图片
        DownloadSatilliteCloudImageCnpoTask(mediumImgUrl, time);

        return ReturnT.SUCCESS;
    }

    /**
     * 获取HTML内容
     *
     * @param
     * @return
     */
    public static Document getHtml1() {
        Document doc = null;

        try {
            doc = Jsoup.connect("http://www.nmc.cn/publish/satellite/China_Northwest_Pacific_Ocean.html")
                    .userAgent("Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0; MALC)")
                    .timeout(999999999)
                    .header("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8")
                    .header("Accept-Encoding", "gzip, deflate")
                    .header("Accept-Language", "zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3")
                    .header("Connection", "keep-alive")
                    //是忽略请求类型
                    .ignoreContentType(true)
                    .get();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return doc;
    }
    private void DownloadSatilliteCloudImageCnpoTask(String imgUrl, String time) {
        QxMap qxMap;
        HttpURLConnection connection;
//        if (imgUrl.length() > 0 && time.length() > 0) {
          //  qxMapMapper = SpringContextHolder.getBean(QxMapMapper.class);
            // 根据时间和图像类型判断当前图片是否已下载
            String type = 7+"";
   //         qxMap = qxMapMapper.selectByTime(time,type);
//            if (qxMap == null) {
         InputStream in = null;
               FileOutputStream fo = null;
                try {
                    String imageName = imgUrl.substring(imgUrl.lastIndexOf("/") + 1, imgUrl.length());
                    imageName = imageName.substring(0, imageName.lastIndexOf("?"));
                    URL uri = new URL(imgUrl);
//                    if (constUtil.useProxy) {
//                        // 设置代理
//                        Proxy proxy = new Proxy(Proxy.Type.DIRECT.HTTP, new InetSocketAddress(constUtil.proxyId, constUtil.proxyPort));
//                        connection = (HttpURLConnection) uri.openConnection(proxy);
               //     } else {
                        connection = (HttpURLConnection) uri.openConnection();
               //     }
                    in = connection.getInputStream();
                    String nowTime = CmUtil.date2day(null);
                    File f = new File(constUtil.cnpoRealPathWlmq + "/" + nowTime);
                    if (!f.exists() && !f.isDirectory()) {
                        f.mkdirs();
                    }
                   String path = "C:\\Users\\LONGS\\Desktop\\photo" + "/" + nowTime + "/" + imageName;
                   fo = new FileOutputStream(new File(path));
                   byte[] buf = new byte[1024];
                    int length = 0;
                   while ((length = in.read(buf, 0, buf.length)) != -1) {
                        fo.write(buf, 0, length);
                    }
                  //  String filePath = TusFileUtils.fileUpload(connection, constUtil.tusdUrl);
                    //写入数据库
//                    qxMap = new QxMap();
//                    qxMap.setId(UUID.randomUUID().toString());
//                    qxMap.setCreatetime(null);
//                    qxMap.setType("7");
//                    qxMap.setFilename(imageName);
//                    qxMap.setFilepath("1111111111111111");
//                    qxMap.setPublishtime(time);
//                    qxMapMapper.insert(qxMap);
                  //  this.taskContents = "下载完成：imgUrl=" + imgUrl + "______time=" + time;
                }
                catch (Exception e) {
                    e.printStackTrace();
                   // this.taskContents = "下载异常：imgUrl=" + imgUrl + "______time=" + time;
                } finally {
                    try {
                        if (fo != null) {
                            fo.flush();
                            fo.close();
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    try {
                        if (in != null) {
                            in.close();
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }


//            private QxWeatherMapper qxWeatherMapper;
//
//    @XxlJob(value = "WeatherDataFor1dayTask", init = "init", destroy = "destroy")
//    public ReturnT<String> WeatherDataFor1dayTask(String param) throws Exception {
//        ConstUtil constUtil = new ConstUtil();
//        String weatherUrl = "";
//        HashMap<String,String> district = new HashMap<>();
//        district.put(constUtil.distName,constUtil.distDodayId);
////        district.put("崂山","laoshan-district");
////        district.put("市南","shinan-district");
////        district.put("即墨","jimo");
////        district.put("胶州","jiaozhou");
////        district.put("黄岛","huangdao-district");
////        district.put("莱西","laixi");
////        district.put("平度","pingdu");
////        district.put("市北","shibei-district");
////        district.put("李沧","licang-district");
////        district.put("城阳","chengyang-district");
////          district.put("乌鲁木齐市","urumqi");
//        // 青岛市天气数据网址前缀
//        String weatherBaseUrl = "https://tianqi.moji.com/today/china/shandong/";
//        // 循环获取各区市天气数据
//        //        String szContent = openFile( "F:/ceshiHtml/mojiHTml.html");
//        //        Parser parser = Parser.createParser(szContent, "utf-8");
//        // 修改 无效Map Iterator
//        Iterator<Map.Entry<String, String>> iterator  = district.entrySet().iterator();
//        Map.Entry<String, String> entry = null;
//        while (iterator.hasNext()) {
//            entry = iterator.next();
//            String key = entry.getKey();
//            QxWeather qxWeather;
//            try{
//                weatherUrl = weatherBaseUrl+district.get(key);
//                // 获取html文本内容
//                Document doc = getHtml3();
//               // if (doc == null) return;
//                // 获取当天时间
//                String nowDate = CmUtil.date2day(null);
//                // 获取地区
//                String dist = key;
//                // 获取一天天气数据
//                Elements elements1 = doc.select("[class=info clearfix]");
//                // 温度
//                String temp = elements1.select("em").text();
//                // 天气
//                String skyCondition = elements1.select("b").text();
//                // 更新时间
//                String updateTime = doc.select("[class=detail_future_title]").select("span").text().substring(0,5);
//                Elements elements2 = doc.select("[class=about clearfix]");
//                // 相对湿度
//                String humidity = elements2.select("span").text().substring(3,elements2.select("span").text().length());
//                // 风向
//                String windDirection = elements2.select("em").text()
//                        .substring(0,elements2.select("em").text().indexOf("风")+1);
//                // 风速
//                String windSpeed = elements2.select("em").text()
//                        .substring(elements2.select("em").text().indexOf("风")+2,elements2.select("em").text().length()-1);
//                // 最高温
//                Element elementsMax = doc.select("[class=day]").first();
//                String maxTemp = elementsMax.select("b").text()
//                        .substring(0,elementsMax.select("b").text().indexOf("°"));
//                // 最低温
//                Element elementsMin = doc.select("[class=day]").last();
//                String minTemp = elementsMin.select("b").text()
//                        .substring(0,elementsMin.select("b").text().indexOf("°"));
//
//                ArrayList<String>weatherList = new ArrayList<>();
//                weatherList.add(maxTemp);
//                weatherList.add(minTemp);
//                weatherList.add(windDirection);
//                weatherList.add(windSpeed);
//                weatherList.add(skyCondition);
//                weatherList.add(temp);
//                weatherList.add(humidity);
//                // 查询天气数据（当天）是否存在
//                String urbanDistrict = key;
//                String wKind = "today";
//                qxWeather = qxWeatherMapper.selectToday(nowDate,wKind,urbanDistrict);
//                if(qxWeather==null){
//                    // 不存在，插入一条新数据
//                    try {
//                        qxWeather = new QxWeather();
//                        qxWeather.setId(CmUtil.getUUID());
//                        qxWeather.setCreateTime(CmUtil.date2db(null));
//                        qxWeather.setWtime(updateTime);
//                        qxWeather.setDist(key);
//                        qxWeather.setWdate(nowDate);
//                        qxWeather.setTemp(temp);
//                        qxWeather.setSkyCondition(skyCondition);
//                        qxWeather.setHumidity(humidity);
//                        qxWeather.setWindDirection(windDirection);
//                        qxWeather.setWindSpeed(windSpeed);
//                        qxWeather.setMaxTemp(maxTemp);
//                        qxWeather.setMinTemp(minTemp);
//                        // 数据类型(1day)
//                        qxWeather.setWkind("today");
//                        // 存入数据库
//                        qxWeatherMapper.insertSelective(qxWeather);
//                       // this.taskContents = "插入"+dist+" "+nowDate+" "+"天气数据成功！";
//                    }catch (Exception e){
//                        e.printStackTrace();
//                        //this.taskContents = "插入"+dist+" "+nowDate+" "+"天气数据异常！";
//                    }
//
//                }else if(!qxWeather.toString2().equals(weatherList.toString())){
//                    // 更新已有数据
//                    try{
//                        qxWeather.setWtime(updateTime);
//                        qxWeather.setTemp(temp);
//                        qxWeather.setSkyCondition(skyCondition);
//                        qxWeather.setHumidity(humidity);
//                        qxWeather.setWindDirection(windDirection);
//                        qxWeather.setWindSpeed(windSpeed);
//                        qxWeather.setMaxTemp(maxTemp);
//                        qxWeather.setMinTemp(minTemp);
//                        // 更新数据库
//                        qxWeatherMapper.updateByPrimaryKeySelective(qxWeather);
//                     //   this.taskContents = "更新"+dist+" "+nowDate+" "+"天气数据成功！";
//                    }catch (Exception e){
//                        e.printStackTrace();
//                       // this.taskContents = "更新"+dist+" "+nowDate+" "+"天气数据异常！";
//                    }
//                }
//              //  this.taskContents = "日期转换成功！";
//            }catch (Exception e){
//                e.printStackTrace();
//               // this.taskContents = "日期转换异常！";
//            }
//        }
//        return ReturnT.SUCCESS;
//    }
//    public static Document getHtml3() {
//        Document doc = null;
//        try {
//                doc = Jsoup.connect("https://tianqi.moji.com/today/china/shandong/")
//                        .userAgent("Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0; MALC)")
//                        .timeout(999999999)
//                        .header("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8")
//                        .header("Accept-Encoding", "gzip, deflate")
//                        .header("Accept-Language", "zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3")
//                        .header("Connection", "keep-alive")
//                        //是忽略请求类型
//                        .ignoreContentType(true)
//                        .get();
//
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//        return doc;
//    }
//
//    public static String openFile( String szFileName ) {
//        String ENCODE = "utf-8";
//        BufferedReader bis = null;
//        try {
//            bis = new BufferedReader(new InputStreamReader(new FileInputStream(new File(szFileName)), ENCODE));
//            String szContent = "";
//            String szTemp;
//
//            while ((szTemp = bis.readLine()) != null) {
//                szContent += szTemp + "\n";
//            }
//            return szContent;
//        } catch (Exception e) {
//            return "";
//        } finally {
//            try {
//                bis.close();
//            } catch (IOException e) {
//                e.printStackTrace();
//            }
//        }
//    }
    public void init(){
        logger.info("init");
    }
    public void destroy(){
        logger.info("destory");
    }


}
